/**
 * Eova Upload
 */
(function ($) {
	/**
	 * 文件上传内核
	 */
	$.uploadcore = {
			/* 提供给外部的接口 */
			filterFile: function (files) { // 提供给外部的过滤文件格式等的接口，外部需要把过滤后的文件返回

			},
			onSelect: function (selectFile, files) { // 提供给外部获取选中的文件，供外部实现预览等功能  selectFile:当前选中的文件  allFiles:还没上传的全部文件

			},
			onDelete: function (file, files) { // 提供给外部获取删除的单个文件，供外部实现删除效果  file:当前删除的文件  files:删除之后的文件

			},
			onProgress: function (file, loaded, total) { // 提供给外部获取单个文件的上传进度，供外部实现上传进度效果

			},
			onSuccess: function (file, result) { // 提供给外部获取单个文件上传成功，供外部实现成功效果

			},
			onFailure: function (file, result) { // 提供给外部获取单个文件上传失败，供外部实现失败效果

			},
			onComplete: function (msg) { // 提供给外部获取全部文件上传完成，供外部实现完成效果

			},

			/* 内部实现功能方法 */
			// 获得选中的文件
			//文件拖放
			funDragHover: function (e) {
				e.stopPropagation();
				e.preventDefault();
				this[e.type === "dragover" ? "onDragOver" : "onDragLeave"].call(e.target);
				return this;
			},
			// 获取文件
			funGetFiles: function (e) {
				var self = this;
				// 取消鼠标经过样式
				this.funDragHover(e);
				// 从事件中获取选中的所有文件
				var files = e.target.files || e.dataTransfer.files;
				self.lastUploadFile = this.uploadFile;
				this.uploadFile = this.uploadFile.concat(this.filterFile(files));
				var tmpFiles = [];

				// 因为jquery的inArray方法无法对object数组进行判断是否存在于，所以只能提取名称进行判断
				var lArr = []; // 之前文件的名称数组
				var uArr = []; // 现在文件的名称数组
				$.each(self.lastUploadFile, function (k, v) {
					lArr.push(v.name);
				});
				$.each(self.uploadFile, function (k, v) {
					uArr.push(v.name);
				});

				$.each(uArr, function (k, v) {
					// 获得当前选择的每一个文件   判断当前这一个文件是否存在于之前的文件当中
					if ($.inArray(v, lArr) < 0) { // 不存在
						tmpFiles.push(self.uploadFile[k]);
					}
				});

				// 如果tmpFiles进行过过滤上一次选择的文件的操作，需要把过滤后的文件赋值
				//if(tmpFiles.length!=0){
				this.uploadFile = tmpFiles;
				//}

				// 调用对文件处理的方法
				this.funDealtFiles();

				return true;
			},
			// 处理过滤后的文件，给每个文件设置下标
			funDealtFiles: function () {
				var self = this;
				// 目前是遍历所有的文件，给每个文件增加唯一索引值
				$.each(this.uploadFile, function (k, v) {
					// 因为涉及到继续添加，所以下一次添加需要在总个数的基础上添加
					v.index = self.fileNum;
					// 添加一个之后自增
					self.fileNum++;
				});
				// 先把当前选中的文件保存备份
				var selectFile = this.uploadFile;
				// 要把全部的文件都保存下来，因为删除所使用的下标是全局的变量
				this.perUploadFile = this.perUploadFile.concat(this.uploadFile);
				// 合并下上传的文件
				this.uploadFile = this.lastUploadFile.concat(this.uploadFile);

				// 执行选择回调
				this.onSelect(selectFile, this.uploadFile);
				//			console.info("继续选择");
				//			console.info(this.uploadFile);
				return this;
			},
			// 处理需要删除的文件  isCb代表是否回调onDelete方法  
			// 因为上传完成并不希望在页面上删除div，但是单独点击删除的时候需要删除div   所以用isCb做判断
			funDeleteFile: function (delFileIndex, isCb) {
				var self = this;

				var tmpFile = []; // 用来替换的文件数组
				// 待删除的文件
				var delFile = this.perUploadFile[delFileIndex];
				console.info(delFile);
				// 目前是遍历所有的文件，对比每个文件  删除
				$.each(this.uploadFile, function (k, v) {
					if (delFile != v) {
						// 如果不是删除的那个文件 就放到临时数组中
						tmpFile.push(v);
					} else {

					}
				});
				this.uploadFile = tmpFile;
				if (isCb) { // DOM物理删除
					// 删除回调
					self.onDelete(delFile, this.uploadFile);
				}

				console.info("还剩这些文件没有上传:");
				console.info(this.uploadFile);
				return true;
			},
			// 上传多个文件
			funUploadFiles: function () {
				var self = this; // 在each中this指向没个v  所以先将this保留
				// 遍历所有文件  ，在调用单个文件上传的方法
				$.each(this.uploadFile, function (k, v) {
					self.funUploadFile(v);
				});
			},
			// 上传单个个文件
			funUploadFile: function (file) {
				var self = this; // 在each中this指向没个v  所以先将this保留

				var formdata = new FormData();
				formdata.append("upload", file);
				var xhr = new XMLHttpRequest();
				// 绑定上传事件
				// 进度
				xhr.upload.addEventListener("progress", function (e) {
					// 回调到外部
					self.onProgress(file, e.loaded, e.total);
				}, false);
				// 完成
				xhr.addEventListener("load", function (e) {
					// 上传完成后, 从待删除列表移除文件
					self.funDeleteFile(file.index, false);
					var result = JSON.parse(xhr.responseText);
					if (result.state == 'ok') {
						// 回调到外部
						self.onSuccess(file, result);
						if (self.uploadFile.length == 0) {
							// 回调全部完成方法
							self.onComplete("全部完成");
						}
					} else {
						// 回调到外部
						self.onFailure(file, JSON.parse(xhr.responseText));
					}

				}, false);
				// 错误
				xhr.addEventListener("error", function (e) {
					// 回调到外部
					self.onFailure(file, JSON.parse(xhr.responseText));
				}, false);
				xhr.open("POST", self.url, true);
				xhr.send(formdata);
			},
			// 返回需要上传的文件
			funReturnNeedFiles: function () {
				return this.uploadFile;
			},

			// 初始化
			init: function () { // 初始化方法，在此给选择、上传按钮绑定事件
				var self = this; // 克隆一个自身

				if (this.dragDrop) {
					this.dragDrop.addEventListener("dragover", function (e) {
						self.funDragHover(e);
					}, false);
					this.dragDrop.addEventListener("dragleave", function (e) {
						self.funDragHover(e);
					}, false);
					this.dragDrop.addEventListener("drop", function (e) {
						self.funGetFiles(e);
					}, false);
				}

				// 如果选择按钮存在
				if (self.fileInput) {
					// 绑定change事件
					this.fileInput.addEventListener("change", function (e) {
						self.funGetFiles(e);
					}, false);
				}

				// 如果上传按钮存在
				if (self.uploadInput) {
					// 绑定click事件
					this.uploadInput.addEventListener("click", function (e) {
						self.funUploadFiles(e);
					}, false);
				}
			}	
	}
	
})(jQuery);